package ru.usu.gv.gui.behavior;

import ru.usu.gv.gui.dynamic.DynamicVisPanel;
import ru.usu.gv.gui.layout.fd.ForceDirectedLayoutSettings;
import ru.usu.gv.uicomponents.UIGraph;
import ru.usu.gv.uicomponents.UIVertex;

import javax.media.j3d.Behavior;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.WakeupOnElapsedFrames;
import javax.vecmath.Point3d;

import java.util.HashMap;
import java.util.Map;

/**
 * @author spupyrev
 * 06.11.2009
 */
public abstract class DynamicVisBehavior extends Behavior
{
	protected WakeupOnElapsedFrames w = new WakeupOnElapsedFrames(100);

	public DynamicVisBehavior(BoundingSphere bound)
	{
		setSchedulingBounds(bound);
	}

	@Override
	public void initialize()
	{
		wakeupOn(w);
	}

	protected Map<Integer, Point3d> extractInitialPositions(UIGraph currentGraph, Map<Integer, Map<Integer, Double>> edges)
	{
		Map<Integer, Point3d> positions = new HashMap();
		for (int id : edges.keySet())
			positions.put(id, currentGraph.getVertex(id).getPosition());
		return positions;
	}

	protected boolean setCoordinates(UIGraph uiGraph, Map<Integer, Point3d> positions)
	{
		boolean changed = false;
		for (int index : positions.keySet())
		{
			UIVertex v = uiGraph.getVertex(index);
			if (v.getPosition().distance(positions.get(index)) > 1e-3)
				changed = true;
			v.setPosition(positions.get(index));
		}

		return changed;
	}

	protected ForceDirectedLayoutSettings createLayoutSettings()
	{
		ForceDirectedLayoutSettings settings = new ForceDirectedLayoutSettings();
		DynamicVisPanel dynamicVisPanel = DynamicVisPanel.getInstance();

		settings.setAttractiveExponent(dynamicVisPanel.getAttractionExponent());
		settings.setAttractiveFactor(dynamicVisPanel.getAttractionFactor());
		settings.setGravitationExponent(dynamicVisPanel.getGravitationExponent());
		settings.setGravitationFactor(dynamicVisPanel.getGravitationFactor());
		settings.setRepulsiveExponent(dynamicVisPanel.getRepulsionExponent());
		settings.setRepulsiveFactor(dynamicVisPanel.getRepulsionFactor());
		settings.setMentalExponent(dynamicVisPanel.getMentalExponent());
		settings.setMentalFactor(dynamicVisPanel.getMentalFactor());

		settings.setIterationLimit(1000);
		settings.setAttempts(1);
		settings.setDimensions(2);

		return settings;
	}

	private boolean autorun;

	public void setAutorun(boolean autorun)
	{
		this.autorun = autorun;
		if (autorun)
			start();
		else
			stop();
	}

	public void start()
	{
		if (autorun)
			setEnable(true);
	}

	public void stop()
	{
		setEnable(false);
	}

}
